package com.chb.rpc;

import com.chb.entity.RpcRequest;
import com.chb.interfaces.HelloService;
import com.chb.utils.IoUtils;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

/**
 * @description:
 * @author: CHB
 * @create: 2022-03-14 11:08
 **/
public class RpcProcessHandler implements Runnable {

    private Socket socket;

    private static Map<String,Object> servicePoll = new HashMap<>();

    static {
        servicePoll.put(HelloService .class.getName(),new HelloServiceImpl());
    }

    public RpcProcessHandler(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run() {
        ObjectInputStream inputStream = null;
        ObjectOutputStream outputStream = null;
        try {
            inputStream = new ObjectInputStream(socket.getInputStream());
            RpcRequest request = (RpcRequest) inputStream.readObject();
            Object result = handler(request);
            outputStream = new ObjectOutputStream(socket.getOutputStream());
            outputStream.writeObject(result);
            outputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IoUtils.close(inputStream,outputStream);
        }
    }


    /**
     * 解析请求参数调用业务方法
     * @param request
     * @return
     * @throws Exception
     */
    private Object handler(RpcRequest request) throws Exception {
        // Class<?> aClass = Class.forName(request.getClassName());
        Object obj = servicePoll.get(request.getClassName());
        Class aClass = obj.getClass();
        Object[] parameters = request.getParameters();

        Class<?>[] parameterType = new Class[parameters.length];
        System.out.println(request);
        for (int i = 0 ; i < parameters.length ; i++){
            parameterType[i] = parameters[i].getClass();
        }
        Method method = aClass.getMethod(request.getMethodName(),parameterType);
        return method.invoke(obj, parameters);
    }

}
